import React, { useState } from 'react';
/**
 * setState 在18版本之前，只有在react合成事件与生命周期内是异步的，在原生事件与定时器内是同步的，在18版本后，react 将所有setState都改为异步执行
 * react通过事务（是 React 中用于包装和管理方法执行的一种设计模式，通过封装逻辑来管理执行上下文，确保操作的一致性和可维护性）与调度器来实现批量更新，
 *    在react合成事件内触发setState后会开启一个事务，收集所有的setState调用，并在事务结束时合并更新
 *
 * 合成事件：react将原生事件进行了一次封装，解决了跨平台的差异，并提供了类似的api，通过事件委托，将事件绑定到根节点上，通过冒泡机制拦截子组件的事件
 * 在合成事件对象中提供了与原有类似的api，并且对这个合成事件对象进行复用，每次使用结束后都清空这个对象(react18后不进行复用)
 */
const StateSync = () => {
  const [count, setCount] = useState(0);
  const [input, setInput] = useState('');

  const countAdd = () => {
    setCount(v => {
      console.log(v);
      return count + 1;
    });
    setTimeout(() => {
      setCount(v => {
        console.log('setTimeout', v);
        return count + 3;
      });
      setTimeout(() => {
        setCount(v => {
          console.log('setTimeout2', v);
          return count + 2;
        });
      });
    });
  };
  const changeInput = e => {
    console.log(e);
    setInput(e.target.value);
  };
  return (
    <>
      <div onClick={countAdd}>StateSync --- {count}</div>
      <input type='text' onChange={changeInput} value={input} />
    </>
  );
};

export default StateSync;
/**
 * Fiber 是react16引入的一种更新模式，15版本之前由于更新是递归进行的，会导致页面阻塞，
 *    fiber将一次更新拆分成多个小任务，通过浏览器的requestIdolCallback进行控制何时进行处理，
 *    每个组件对象中都包含child return sibling组成链表，并且维护了2个dom树，更新在work树中进行（对其进行增量更新），更新完成后替换current树
 */
